﻿#region Header

/*
    This file is part of nDoctor Light

    NDoctor is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    NDoctor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with NDoctor.  If not, see <http://www.gnu.org/licenses/>.
*/

#endregion Header

namespace Probel.Ldoc.ViewModels.Pages
{
    using System;
    using System.Collections.ObjectModel;
    using System.Windows.Input;

    using Probel.Ldoc.Services.Dto;
    using Probel.Ldoc.Services.Services;
    using Probel.Ldoc.ViewModels.Controls;
    using Probel.Ldoc.ViewModels.Controls.Corectors;
    using Probel.Ldoc.ViewModels.Properties;
    using Probel.Mvvm.DataBinding;
    using Probel.Mvvm.Gui;

    public class IncoherencesViewModel : BaseViewModel
    {
        #region Fields

        private readonly ICommand analyseCommand;
        private readonly ICommand fixCommand;
        private readonly IPatientService Service;

        private Action FixAction;

        #endregion Fields

        #region Constructors

        public IncoherencesViewModel(IPatientService service, IErrorService errorService, bool isAsync = true)
            : base(errorService, isAsync)
        {
            this.Service = service;

            this.Result = new ObservableCollection<IncoherenceDto>();

            this.analyseCommand = new RelayCommand(this.Analyse);
            this.fixCommand = new RelayCommand(this.Fix, () => this.CanFix);
        }

        #endregion Constructors

        #region Properties

        public ICommand AnalyseCommand
        {
            get { return this.analyseCommand; }
        }

        public bool CanFix
        {
            get;
            set;
        }

        public ICommand FixCommand
        {
            get { return this.fixCommand; }
        }

        public ObservableCollection<IncoherenceDto> Result
        {
            get;
            private set;
        }

        #endregion Properties

        #region Methods

        public LowerCaseCorectorViewModel BuildInsuranceLowerCaseViewModel()
        {
            this.CanFix = true;
            var result = new LowerCaseCorectorViewModel(this.ErrorService, Messages.Fix_Insurance, this.IsAsync);
            this.Async(() => this.Service.GetLowerCasedInsurances()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.CanFix = false;
                              this.Service.FixLowerCaseInsurances();
                              ViewService.MessageBox.Information(Messages.Msg_Fixed);
                              result.ItemsToFix.Clear();
                              this.Analyse();
                          };
                      });

            return result;
        }

        public InsuranceSpellingCorectorViewModel BuildInsuranceSpellingCorectorViewModel()
        {
            this.CanFix = true;
            var result = new InsuranceSpellingCorectorViewModel(this, this.ErrorService, this.Service, this.IsAsync);
            this.Async(() => this.Service.GetInsurancesToFix()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.CanFix = false;
                              this.Async(() => result.Fix()
                                       , () =>
                                       {
                                           result.ClearLists();
                                           result.ItemsToFix.Clear();
                                           this.Analyse();
                                           ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                       });
                          };
                      });
            return result;
        }

        public LowerCaseCorectorViewModel BuildPracticeLowerCaseViewModel()
        {
            this.CanFix = true;
            var result = new LowerCaseCorectorViewModel(this.ErrorService, Messages.Fix_Practice, this.IsAsync);
            this.Async(() => this.Service.GetLowerCasedPractices()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.Async(() => this.Service.FixLowerCasePractices()
                                       , () =>
                                       {
                                           this.CanFix = false;
                                           ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                           result.ItemsToFix.Clear();
                                           this.Analyse();
                                       });
                          };
                      });
            return result;
        }

        public LowerCaseCorectorViewModel BuildProfessionLowerCaseViewModel()
        {
            this.CanFix = true;
            var result = new LowerCaseCorectorViewModel(this.ErrorService, Messages.Fix_Profession, this.IsAsync);
            this.Async(() => this.Service.GetLowerCasedProfessions()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.CanFix = false;
                              this.Async(() => this.Service.FixLowerCaseProfessions()
                                  , () =>
                                  {
                                      result.ItemsToFix.Clear();
                                      this.Analyse();
                                      ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                  });
                          };
                      });
            return result;
        }

        public ProfessionSpellingCorectorViewModel BuildProfessionSpellingCorrectorViewModel()
        {
            this.CanFix = true;
            var result = new ProfessionSpellingCorectorViewModel(this, this.ErrorService, this.Service, this.IsAsync);
            this.Async(() => this.Service.GetProfessionsToFix()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.CanFix = false;
                              this.Async(() => result.Fix()
                                       , () =>
                                       {
                                           result.ClearLists();
                                           result.ItemsToFix.Clear();
                                           this.Analyse();
                                           ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                       });
                          };
                      });
            return result;
        }

        public LowerCaseCorectorViewModel BuildReputationLowerCaseViewModel()
        {
            this.CanFix = true;
            var result = new LowerCaseCorectorViewModel(this.ErrorService, Messages.Fix_Reputation, this.IsAsync);
            this.Async(() => this.Service.GetLowerCasedReputations()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.Async(() => this.Service.FixLowerCaseReputations()
                                  , () =>
                                  {
                                      this.CanFix = false;
                                      ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                      result.ItemsToFix.Clear();
                                      this.Analyse();
                                  });
                          };
                      });
            return result;
        }

        public ReputationSpellingCorectorViewModel BuildReputationSpellingCorrectorViewModel()
        {
            this.CanFix = true;
            var result = new ReputationSpellingCorectorViewModel(this, this.ErrorService, this.Service, this.IsAsync);
            this.Async(() => this.Service.GetReputationsToFix()
                      , t =>
                      {
                          result.ItemsToFix.Refill(t);
                          this.FixAction = () =>
                          {
                              this.CanFix = false;
                              this.Async(() => result.Fix()
                                       , () =>
                                       {
                                           result.ClearLists();
                                           result.ItemsToFix.Clear();
                                           this.Analyse();
                                           ViewService.MessageBox.Information(Messages.Msg_Fixed);
                                       });
                          };
                      });
            return result;
        }

        private void Analyse()
        {
            this.Async(() => this.Service.AnalyseIncoherences()
                      , t => this.Result.Refill(t));
        }

        private void Fix()
        {
            if (this.FixAction != null)
            {
                this.FixAction();
            }
            else { throw new NullReferenceException("Impossible to fix the issue bacause there's not fix configured!"); }
        }

        #endregion Methods
    }
}